package com.ruoyi.project.manage.project.controller;

import com.ruoyi.common.constant.ProjectConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.utils.bean.BeanUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.framework.aspectj.lang.annotation.Excel;
import com.ruoyi.framework.web.controller.BaseController;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.manage.approveLog.domain.ApproveLog;
import com.ruoyi.project.manage.approveLog.service.IApproveLogService;
import com.ruoyi.project.manage.item.domain.ProjectItem;
import com.ruoyi.project.manage.item.service.IProjectItemService;
import com.ruoyi.project.manage.project.domain.Project;
import com.ruoyi.project.manage.project.service.IProjectService;
import com.ruoyi.project.manage.project.service.IProjectStatService;
import com.ruoyi.project.system.dict.domain.DictData;
import com.ruoyi.project.system.dict.service.IDictDataService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 项目统计Controller，适用于大屏展示
 *
 * 1. 全域
 *  /stat/project/areaList      获取区域列表，区域字典数据
 *  /stat/project/all/count     统计已审核项目数量
 *  /stat/project/area/count    统计各区域项目总数、总投资
 * 2. 区域
 *
 * 3. 公用
 * /stat/project/dictData       查询字典数据
 *
 * @author fangkun
 * @date 2022-03-28
 */
@Controller
@RequestMapping("/stat/project")
public class ProjectStatController extends BaseController {

    @Autowired
    private IDictDataService dictDataService;

    @Autowired
    private IProjectStatService projectStatService;
    @Autowired
    private IProjectService projectService;
    @Autowired
    private IProjectItemService projectItemService;
    @Autowired
    private IApproveLogService approveLogService;

    @GetMapping("/dictData")
    @ResponseBody
    public AjaxResult getDictData() {
        DictData param = new DictData();
        param.setDictType("eb_project_area");
        List<DictData> dictData = dictDataService.selectDictDataList(param);

        param.setDictType("eb_project_type");
        dictData.addAll(dictDataService.selectDictDataList(param));

        param.setDictType("eb_project_label");
        dictData.addAll(dictDataService.selectDictDataList(param));

        param.setDictType("eb_project_industry");
        dictData.addAll(dictDataService.selectDictDataList(param));

        param.setDictType("eb_construction_type");
        dictData.addAll(dictDataService.selectDictDataList(param));

        param.setDictType("eb_project_stage");
        dictData.addAll(dictDataService.selectDictDataList(param));

        param.setDictType("eb_project_progress");
        dictData.addAll(dictDataService.selectDictDataList(param));

        List<DictDataInterface> dictDataInterfaces = new DicDataUtil().dto2Domain(dictData);
        return AjaxResult.success(dictDataInterfaces);
    }

    /**
     * 获取区域信息
     * @return 区域信息列表
     */
    @GetMapping("/areaList")
    @ResponseBody
    public AjaxResult getAreaList() {
        DictData param = new DictData();
        param.setDictType("eb_project_area");
        List<DictData> dictData = dictDataService.selectDictDataList(param);

        List<DictDataInterface> dictDataInterfaces = new DicDataUtil().dto2Domain(dictData);
        return AjaxResult.success(dictDataInterfaces);
    }

    // --- 全域 ---
    /**
     * 项目总数统计
     * @return 项目总数
     */
    @GetMapping("/all/count")
    @ResponseBody
    public AjaxResult getAllCount() {
        int allCount = projectStatService.getAllCount();
        return AjaxResult.success(allCount);
    }

    /**
     * 项目各区域总数统计
     * @return 项目总数
     */
    @GetMapping("/area/count")
    @ResponseBody
    public AjaxResult getAreaCount() {
        List<Map> areaCount = projectStatService.getAreaCount();
        return AjaxResult.success(areaCount);
    }

    /**
     * 投资建设资金情况统计
     * @return 金额
     */
    @GetMapping("/all/invest")
    @ResponseBody
    public AjaxResult getAllInvest() {
        Map allInvest = projectStatService.getAllInvest();
        return AjaxResult.success(allInvest);
    }

    /**
     * 区域 投资建设资金情况统计
     * @return 金额
     */
    @GetMapping("/area/invest")
    @ResponseBody
    public AjaxResult getAreaInvest() {
        List<Map> areaInvest = projectStatService.getAreaInvest();
        return AjaxResult.success(areaInvest);
    }

    /**
     * 项目类型统计/投资额分布情况
     * @return 数量、投资额
     */
    @GetMapping("/all/type")
    @ResponseBody
    public AjaxResult getAllType(String needArea, Project project) {
        List<Map> allType = projectStatService.getAllType(Boolean.valueOf(needArea), project);
        return AjaxResult.success(allType);
    }

    /**
     * 建设性质统计
     * @return 数量
     */
    @GetMapping("/all/constructionType")
    @ResponseBody
    public AjaxResult getAllConstructionType(String needArea) {
        List<Map> allConstructionType = projectStatService.getAllConstructionType(Boolean.valueOf(needArea));
        return AjaxResult.success(allConstructionType);
    }

    /**
     * 项目阶段情况统计
     * @return 数量
     */
    @GetMapping("/all/stage")
    @ResponseBody
    public AjaxResult getAllStage(String needArea) {
        List<Map> allStage = projectStatService.getAllStage(Boolean.valueOf(needArea));
        return AjaxResult.success(allStage);
    }

    /**
     * 七大产业集群统计
     * @return 数量
     */
    @GetMapping("/all/industry")
    @ResponseBody
    public AjaxResult getAllIndustryByType(String needArea) {
        List<Map> allIndustryByType = projectStatService.getAllIndustryByType(Boolean.valueOf(needArea));
        return AjaxResult.success(allIndustryByType);
    }

    /**
     * “三个一批”项目统计
     * @return 数量
     */
    @GetMapping("/all/progress")
    @ResponseBody
    public AjaxResult getAllProgress(String needArea) {
        List<Map> allProgress = projectStatService.getAllProgress(Boolean.valueOf(needArea));
        return AjaxResult.success(allProgress);
    }

    @GetMapping("/all/project")
    @ResponseBody
    public AjaxResult getProjectByKey(String keyword) {
        Project project = new Project();
        project.setProjectName(keyword);
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);

        List<Map> areasProject = projectStatService.getAreasProject(project);
        return AjaxResult.success(areasProject);
    }

    /**
     * 以上接口组合
     * @return
     */
    @GetMapping("/all/union")
    @ResponseBody
    public AjaxResult getAllUnion() {
        DictData param = new DictData();
        param.setDictType("eb_project_area");
        List<DictData> dictData = dictDataService.selectDictDataList(param);
        // 区域信息列表
        List<DictDataInterface> allAreas = new DicDataUtil().dto2Domain(dictData);
        // 投资建设资金情况统计
        Map allInvest = projectStatService.getAllInvest();
        // 项目类型统计/投资额分布情况
        List<Map> allType = projectStatService.getAllType(false, null);
        // 区域类型统计/投资额分布情况
        List<Map> areaType = projectStatService.getAllType(true, null);
        // 建设性质统计
        List<Map> allConstructionType = projectStatService.getAllConstructionType(false);
        // 区域建设性质统计
        List<Map> areaConstructionType = projectStatService.getAllConstructionType(true);
        // 项目阶段情况统计
        List<Map> allStage = projectStatService.getAllStage(false);
        // 区域项目阶段情况统计
        List<Map> areaStage = projectStatService.getAllStage(true);
        // 七大产业集群统计
        List<Map> allIndustryByType = projectStatService.getAllIndustryByType(false);
        // 区域七大产业集群统计
        List<Map> areaIndustryByType = projectStatService.getAllIndustryByType(true);
        // “三个一批”项目统计
        List<Map> allProgress = projectStatService.getAllProgress(false);
        // 区域“三个一批”项目统计
        List<Map> areaProgress = projectStatService.getAllProgress(true);
        // 项目各区域总数统计
        List<Map> areaCount = projectStatService.getAreaCount();
        // 区域投资额统计
        List<Map> areaInvest = projectStatService.getAreaInvest();

        Map allUnion = new HashMap();
        allUnion.put("allAreas", allAreas);
        allUnion.put("allInvest", allInvest);
        allUnion.put("allType", allType);
        allUnion.put("allConstructionType", allConstructionType);
        allUnion.put("allStage", allStage);
        allUnion.put("allIndustryByType", allIndustryByType);
        allUnion.put("allProgress", allProgress);
        allUnion.put("areaCount", areaCount);

        allUnion.put("areaType", areaType);
        allUnion.put("areaConstructionType", areaConstructionType);
        allUnion.put("areaStage", areaStage);
        allUnion.put("areaIndustryByType", areaIndustryByType);
        allUnion.put("areaProgress", areaProgress);
        allUnion.put("areaInvest", areaInvest);

        return AjaxResult.success(allUnion);
    }


    // --- 各区 ---
    /**
     * 各区项目数量统计
     * @return 数量
     */
    @GetMapping("/{projectArea}/count")
    @ResponseBody
    public AjaxResult getAreasCount(@PathVariable("projectArea") Integer projectArea) {
        Integer areasCount = projectStatService.getAreasCount(projectArea);
        return AjaxResult.success(areasCount);
    }

    /**
     * 各区投资建设资金情况统计
     * @return 金额
     */
    @GetMapping("/{projectArea}/invest")
    @ResponseBody
    public AjaxResult getAreasInvest(@PathVariable("projectArea") Integer projectArea) {
        Map areasInvest = projectStatService.getAreasInvest(projectArea);
        return AjaxResult.success(areasInvest);
    }

    /**
     * 各区项目清单
     */
    @GetMapping("/{projectArea}/project")
    @ResponseBody
    public AjaxResult getAreasProject(@PathVariable("projectArea") Integer projectArea, Project project) {
        if (project == null) {
            project = new Project();
        }
        project.setProjectArea(projectArea);
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);

        return AjaxResult.success(projectStatService.getAreasProject(project));
    }

    /**
     * 各区项目类型统计/投资额分布情况
     * @return 数量、投资额
     */
    @GetMapping("/{projectArea}/type")
    @ResponseBody
    public AjaxResult getAreasType(@PathVariable("projectArea") Integer projectArea) {

        List<Map> areasType = projectStatService.getAreasType(projectArea);
        return AjaxResult.success(areasType);
    }

    /**
     * 各区建设性质统计
     * @return 数量
     */
    @GetMapping("/{projectArea}/constructionType")
    @ResponseBody
    public AjaxResult getAreasConstructionType(@PathVariable("projectArea") Integer projectArea) {

        List<Map> areasConstruction = projectStatService.getAreasConstructionType(projectArea);
        return AjaxResult.success(areasConstruction);
    }

    /**
     * 各区项目阶段情况统计
     * @return 数量
     */
    @GetMapping("/{projectArea}/stage")
    @ResponseBody
    public AjaxResult getAreasStage(@PathVariable("projectArea") Integer projectArea) {

        List<Map> areasStage = projectStatService.getAreasStage(projectArea);
        return AjaxResult.success(areasStage);
    }

    /**
     * 各区七大产业集群统计
     * @return 数量
     */
    @GetMapping("/{projectArea}/industry")
    @ResponseBody
    public AjaxResult getAreasIndustryByType(@PathVariable("projectArea") Integer projectArea) {

        List<Map> areasIndustry = projectStatService.getAreasIndustryByType(projectArea);
        return AjaxResult.success(areasIndustry);
    }

    /**
     * 各区“三个一批”项目统计
     * @return 数量
     */
    @GetMapping("/{projectArea}/progress")
    @ResponseBody
    public AjaxResult getAreasProgress(@PathVariable("projectArea") Integer projectArea) {

        List<Map> areasProgress = projectStatService.getAreasProgress(projectArea);
        return AjaxResult.success(areasProgress);
    }

    @GetMapping("/{projectId}/map")
    @ResponseBody
    public AjaxResult getProjectMap(@PathVariable("projectId") Long projectId) {
        // 获取项目关联事项
        ProjectItem projectItem = new ProjectItem();
        projectItem.setProjectId(projectId);
        projectItem.setStatus(UserConstants.NORMAL);
        projectItem.setIsClose(ProjectConstants.YES);
        List<ProjectItem> projectItems = projectItemService.selectProjectItemList(projectItem);

        return AjaxResult.success(projectItems);
    }

    @GetMapping("/{projectId}/log")
    @ResponseBody
    public AjaxResult getProjectLog(@PathVariable("projectId") Long projectId) {
        // 获取项目日志
        ApproveLog approveLog = new ApproveLog();
        approveLog.setEntityType(ProjectConstants.APPROVAL_TYPE_LOG);
        approveLog.setEntityId(projectId);
        List<ApproveLog> approveLogs = approveLogService.selectApproveLogList(approveLog);
        return AjaxResult.success(approveLogs);
    }

    /**
     * 以上各区接口组合
     * @return
     */
    @GetMapping("/{projectArea}/union")
    @ResponseBody
    public AjaxResult getAreasUnion(@PathVariable("projectArea") Integer projectArea) {
        // 各区投资建设资金情况统计
        Map areasInvest = projectStatService.getAreasInvest(projectArea);
        // 各区项目类型统计/投资额分布情况
        List<Map> areasType = projectStatService.getAreasType(projectArea);
        // 各区建设性质统计
        List<Map> areasConstruction = projectStatService.getAreasConstructionType(projectArea);
        // 各区项目阶段情况统计
        List<Map> areasStage = projectStatService.getAreasStage(projectArea);
        // 各区七大产业集群统计
        List<Map> areasIndustry = projectStatService.getAreasIndustryByType(projectArea);
        // 各区“三个一批”项目统计
        List<Map> areasProgress = projectStatService.getAreasProgress(projectArea);

        // 各区项目清单
        Project project = new Project();
        project.setProjectArea(projectArea);
        project.setProjectStatus(ProjectConstants.APPROVAL_AGREE);

        List<Map> areasProject = projectStatService.getAreasProject(project);

        Map areasUnion = new HashMap();
        areasUnion.put("areasInvest", areasInvest);
        areasUnion.put("projects", areasProject);
        areasUnion.put("areasType", areasType);
        areasUnion.put("areasConstruction", areasConstruction);
        areasUnion.put("areasStage", areasStage);
        areasUnion.put("areasIndustry", areasIndustry);
        areasUnion.put("areasProgress", areasProgress);

        return AjaxResult.success(areasUnion);
    }

    private class DictDataInterface {
        /** 字典标签 */
        private String dictLabel;

        /** 字典键值 */
        private String dictValue;

        /** 字典类型 */
        private String dictType;

        public String getDictLabel() {
            return dictLabel;
        }

        public void setDictLabel(String dictLabel) {
            this.dictLabel = dictLabel;
        }

        public String getDictValue() {
            return dictValue;
        }

        public void setDictValue(String dictValue) {
            this.dictValue = dictValue;
        }

        public String getDictType() {
            return dictType;
        }

        public void setDictType(String dictType) {
            this.dictType = dictType;
        }
    }

    private class DicDataUtil {
        public DictDataInterface dto2Domain(DictData dictData){
            if(dictData==null) return null;
            DictDataInterface dictDataInterface = new DictDataInterface();
            BeanUtils.copyProperties(dictData,dictDataInterface);

            return dictDataInterface;
        }

        public List<DictDataInterface> dto2Domain(List<DictData> dtoList){
            if(dtoList==null || dtoList.isEmpty()) return null;

            List<DictDataInterface> domainList = new ArrayList<>();
            for(DictData dto : dtoList){
                domainList.add(dto2Domain(dto));
            }
            return domainList;
        }
    }
}
